package com.yuqiao.read.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;

import java.lang.reflect.Type;
import java.util.Map;

/**
 * spring applicationContext 存储，方便获取
 * 
 * @author RandyJie
 * @version 2016-09-29
 * 
 */
public class WscApplicationContext {

	private static ApplicationContext applicationContext;

	public static void setApplicationContext(ApplicationContext ac) throws BeansException {
		if (applicationContext == null)
			applicationContext = ac;
	}

	/**
	 * 获取spring 容器上下文
	 * 
	 * @return
	 */
	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/**
	 * 获取bean
	 * 
	 * @param type
	 * @return
	 */
	public static <T> T getBeanOfType(Class<T> type) {
		Map<String, T> map = applicationContext.getBeansOfType(type);
		for (ApplicationContext context = applicationContext.getParent(); context != null; context = context
				.getParent()) {
			map.putAll(context.getBeansOfType(type));
		}

		if (map.size() == 0) {
			return null;
		} else if (map.size() == 1) {
			return map.values().iterator().next();
		}

		throw new RuntimeException("Found incorrect number of " + type.getSimpleName() + " instances in "
				+ "application context - you must have only have one!");
	}

	/**
	 * 获取bean
	 * 
	 * @param type
	 *            接口
	 * @param impl
	 *            tpye 的具体实现
	 * @return
	 */
	public static <T> T getBeanOfType(Class<T> type, Type impl) {
		Map<String, T> map = applicationContext.getBeansOfType(type);
		for (ApplicationContext context = applicationContext.getParent(); context != null; context = context
				.getParent()) {
			map.putAll(context.getBeansOfType(type));
		}

		if (map.size() == 0) {
			return null;
		} else if (map.size() == 1) {
			return map.values().iterator().next();
		} else {
			for (T ele : map.values()) {
				if (ele.getClass().getName().equals(impl.getTypeName())) {
					return ele;
				}
			}
		}

		throw new RuntimeException("Found incorrect number of " + type.getSimpleName() + " instances in "
				+ "application context - you must have only have one!");
	}

	/**
	 * 通过name 获取bean
	 * 
	 * @param name
	 * @param type
	 * @return
	 */
	public static <T> T getBeanOfType(String name, Class<T> type) {
		return applicationContext.getBean(name, type);
	}

}
